package com.liang.bishi.nj;

/**
 * 第二题：Java多线程交替打印奇数和偶数
 * 2.2 使用 notify() 和 wait() 来控制线程的执行顺序
 */
public class Problem02_2 {
    private final int maxCount; // 最大数字
    private int current = 1;
    private final Object lock = new Object();

    public Problem02_2(int maxCount) {
        this.maxCount = maxCount;
    }

    // 开启两个线程分别打印奇数和偶数
    public void start() throws InterruptedException {
        // 线程 OddThread 调用 printOdd();
        Thread oddThread = new Thread(() -> {
            while (current <= maxCount) {
                synchronized (lock) {
                    // 判断是否是奇数并打印
                    if (current % 2 != 0) {
                        System.out.println(Thread.currentThread().getName() + "-" + current++);
                        lock.notify(); // 唤醒其他线程，唤醒的线程要获取到锁才能执行
                    } else {
                        try {
                            System.out.println(Thread.currentThread().getName() + "-odd wait-" + current);
                            lock.wait(); // 等待
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }, "OddThread");

        // 线程 EvenThread 调用 printEven();
        Thread evenThread = new Thread(() -> {
            while (current <= maxCount) {
                synchronized (lock) {
                    // 判断是否是偶数并打印
                    if (current % 2 == 0) {
                        System.out.println(Thread.currentThread().getName() + "-" + current++);
                        lock.notify(); // 唤醒其他线程
                    } else {
                        try {
                            System.out.println(Thread.currentThread().getName() + "-even wait-" + current);
                            lock.wait(); // 等待
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }, "EvenThread");

        // 启动两个线程
        oddThread.start();
        evenThread.start();

        // 等待子线程执行完成
        oddThread.join();
        evenThread.join();
    }

    public static void main(String[] args) throws InterruptedException {
        Problem02_2 test02 = new Problem02_2(100);
        test02.start();
    }

}
